<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 22 Webpack with R | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.21 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 22 Webpack with R | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 22 Webpack with R | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2021-04-19" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="webpack-intro-discover.html"/>
<link rel="next" href="packer-adv.html"/>
<script src="libs/jquery-3.5.1/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets-1.5.3/htmlwidgets.js"></script>
<script src="libs/plotly-binding-4.9.3/plotly.js"></script>
<script src="libs/typedarray-0.1/typedarray.min.js"></script>
<link href="libs/crosstalk-1.1.1/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk-1.1.1/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main-1.57.1/plotly-latest.min.js"></script>
<script src="libs/core-js-2.5.3/shim.min.js"></script>
<script src="libs/react-16.12.0/react.min.js"></script>
<script src="libs/react-16.12.0/react-dom.min.js"></script>
<script src="libs/reactwidget-1.0.0/react-tools.js"></script>
<script src="libs/reactable-binding-0.2.3/reactable.js"></script>
<script src="libs/r2d3-render-0.1.0/r2d3-render.js"></script>
<script src="libs/webcomponents-2.0.0/webcomponents.js"></script>
<script src="libs/r2d3-binding-0.2.5/r2d3.js"></script>
<script src="libs/d3v6-6.2.0/d3.min.js"></script>
<script src="libs/viz-1.8.2/viz.js"></script>
<link href="libs/DiagrammeR-styles-0.2/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding-1.0.6.1/grViz.js"></script>
<link href="libs/datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet" />
<script src="libs/datatables-binding-0.17/datatables.js"></script>
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.extra.css" rel="stylesheet" />
<script src="libs/dt-core-1.10.20/js/jquery.dataTables.min.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-74544116-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-74544116-1');
</script>
<meta property="og:title" content="Chapter 22 Webpack with R | JavaScript for R">
<meta property="og:description" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta property="og:image" content="https://book.javascript-for-r.com/images/social.png">
<meta property="og:url" content="https://book.javascript-for-r.com/">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:site_name" content="Chapter 22 Webpack with R | JavaScript for R">
<meta name="twitter:image:alt" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta name="twitter:site" content="@jdatap">


<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a><ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics and Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="intro-overview.html"><a href="intro-overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a><ul>
<li class="chapter" data-level="1.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-overview-rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a><ul>
<li class="chapter" data-level="1.2.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a><ul>
<li class="chapter" data-level="1.3.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-reactr-vuer"><i class="fa fa-check"></i><b>1.3.1</b> reactR &amp; vueR</a></li>
<li class="chapter" data-level="1.3.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a><ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-package-dev"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a><ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-create-pkg"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#basics-installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#basics-build-load-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-json"><i class="fa fa-check"></i><b>2.2</b> JSON</a><ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-tabular"><i class="fa fa-check"></i><b>2.2.2</b> Tabular Data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a><ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-chrome-devtools"><i class="fa fa-check"></i><b>2.3.1</b> Developer Tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-var-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable Declaration and Scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document Object Model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a><ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-static-files"><i class="fa fa-check"></i><b>2.4.1</b> Serving Static Files</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-htmltools"><i class="fa fa-check"></i><b>2.4.2</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-deps-pro-cons"><i class="fa fa-check"></i><b>2.4.3</b> Serving vs. htmltools</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a><ul>
<li class="chapter" data-level="3.1" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-plotly"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-dt"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
<li class="chapter" data-level="3.3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-crosstalk"><i class="fa fa-check"></i><b>3.3</b> Crosstalk</a></li>
<li class="chapter" data-level="3.4" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-conclude"><i class="fa fa-check"></i><b>3.4</b> Wrap-up</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="widgets-basics.html"><a href="widgets-basics.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a><ul>
<li class="chapter" data-level="4.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-study"><i class="fa fa-check"></i><b>4.1</b> Read and Study</a></li>
<li class="chapter" data-level="4.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates"><i class="fa fa-check"></i><b>4.2</b> Candidate Libraries</a><ul>
<li class="chapter" data-level="4.2.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-plotly"><i class="fa fa-check"></i><b>4.2.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.2.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-highcharts"><i class="fa fa-check"></i><b>4.2.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.2.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-chart.js"><i class="fa fa-check"></i><b>4.2.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-inner-workings"><i class="fa fa-check"></i><b>4.3</b> How It Works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="widgets-first.html"><a href="widgets-first.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a><ul>
<li class="chapter" data-level="5.1" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-htmloutput"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-js-files"><i class="fa fa-check"></i><b>5.3</b> JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="widgets-realistic.html"><a href="widgets-realistic.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a><ul>
<li class="chapter" data-level="6.1" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-deps"><i class="fa fa-check"></i><b>6.1</b> Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-implementation"><i class="fa fa-check"></i><b>6.2</b> Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="widgets-full.html"><a href="widgets-full.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a><ul>
<li class="chapter" data-level="7.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-deps"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-js"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a><ul>
<li class="chapter" data-level="7.4.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-js"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify"><i class="fa fa-check"></i><b>7.4.2</b> Modify Serialiser</a></li>
<li class="chapter" data-level="7.4.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-replace"><i class="fa fa-check"></i><b>7.4.3</b> Replace Serialiser</a></li>
<li class="chapter" data-level="7.4.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify-data"><i class="fa fa-check"></i><b>7.4.4</b> Modify the Data</a></li>
<li class="chapter" data-level="7.4.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-conclusion"><i class="fa fa-check"></i><b>7.4.5</b> Pros and Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-on-print"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="widgets-adv.html"><a href="widgets-adv.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a><ul>
<li class="chapter" data-level="8.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-shared"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a><ul>
<li class="chapter" data-level="8.1.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prerender"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks and Security</a></li>
<li class="chapter" data-level="8.4" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-js"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prepend-append"><i class="fa fa-check"></i><b>8.5</b> Prepend and Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a><ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk Examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-req"><i class="fa fa-check"></i><b>9.2</b> Crosstalk Requirements</a></li>
<li class="chapter" data-level="9.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-inner-workings"><i class="fa fa-check"></i><b>9.3</b> How it Works</a><ul>
<li class="chapter" data-level="9.3.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-keys"><i class="fa fa-check"></i><b>9.3.1</b> Keys</a></li>
<li class="chapter" data-level="9.3.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-communication-lines"><i class="fa fa-check"></i><b>9.3.2</b> Communication Lines</a></li>
<li class="chapter" data-level="9.3.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-groups"><i class="fa fa-check"></i><b>9.3.3</b> Groups</a></li>
</ul></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with Gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-r"><i class="fa fa-check"></i><b>9.5</b> R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-js"><i class="fa fa-check"></i><b>9.6</b> JavaScript Code</a><ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-send-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send Selected Keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-set-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set Selected Keys</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-using"><i class="fa fa-check"></i><b>9.7</b> Using Crosstalk with Gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="widgets-final.html"><a href="widgets-final.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a><ul>
<li class="chapter" data-level="10.1" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets and Data</a></li>
<li class="chapter" data-level="10.2" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-interface"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
<li class="chapter" data-level="10.4" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-exercises"><i class="fa fa-check"></i><b>10.4</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="11" data-path="shiny-intro.html"><a href="shiny-intro.html"><i class="fa fa-check"></i><b>11</b> Bidirectional Communication</a><ul>
<li class="chapter" data-level="11.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-websocket"><i class="fa fa-check"></i><b>11.1</b> WebSocket an Shiny</a></li>
<li class="chapter" data-level="11.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-sessions"><i class="fa fa-check"></i><b>11.2</b> Sessions</a></li>
<li class="chapter" data-level="11.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-example"><i class="fa fa-check"></i><b>11.3</b> Alerts, an example</a><ul>
<li class="chapter" data-level="11.3.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-explore"><i class="fa fa-check"></i><b>11.3.1</b> Explore</a></li>
<li class="chapter" data-level="11.3.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-r-to-js"><i class="fa fa-check"></i><b>11.3.2</b> From R to JavaScript</a></li>
<li class="chapter" data-level="11.3.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-serialise"><i class="fa fa-check"></i><b>11.3.3</b> Serialisation</a></li>
<li class="chapter" data-level="11.3.4" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-js2r"><i class="fa fa-check"></i><b>11.3.4</b> JavaScript to R</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="12" data-path="shiny-complete.html"><a href="shiny-complete.html"><i class="fa fa-check"></i><b>12</b> A Complete Integration</a><ul>
<li class="chapter" data-level="12.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-discover"><i class="fa fa-check"></i><b>12.1</b> Discover</a></li>
<li class="chapter" data-level="12.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-setup"><i class="fa fa-check"></i><b>12.2</b> Setup</a></li>
<li class="chapter" data-level="12.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-dependencies"><i class="fa fa-check"></i><b>12.3</b> Dependencies</a></li>
<li class="chapter" data-level="12.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-images"><i class="fa fa-check"></i><b>12.4</b> Static Files</a></li>
<li class="chapter" data-level="12.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-skeleton"><i class="fa fa-check"></i><b>12.5</b> Skeleton</a></li>
<li class="chapter" data-level="12.6" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-r2js"><i class="fa fa-check"></i><b>12.6</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.7" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-js2r"><i class="fa fa-check"></i><b>12.7</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.8" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-input-handler"><i class="fa fa-check"></i><b>12.8</b> Input handler</a></li>
<li class="chapter" data-level="12.9" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg"><i class="fa fa-check"></i><b>12.9</b> As a Package</a><ul>
<li class="chapter" data-level="12.9.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-deps"><i class="fa fa-check"></i><b>12.9.1</b> Dependencies</a></li>
<li class="chapter" data-level="12.9.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-trigger"><i class="fa fa-check"></i><b>12.9.2</b> Trigger classification</a></li>
<li class="chapter" data-level="12.9.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-js-code"><i class="fa fa-check"></i><b>12.9.3</b> JavaScript code</a></li>
<li class="chapter" data-level="12.9.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-input-handler"><i class="fa fa-check"></i><b>12.9.4</b> Input handler</a></li>
<li class="chapter" data-level="12.9.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-test"><i class="fa fa-check"></i><b>12.9.5</b> Test</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="shiny-tips.html"><a href="shiny-tips.html"><i class="fa fa-check"></i><b>13</b> Tips and Tricks</a><ul>
<li class="chapter" data-level="13.1" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-events"><i class="fa fa-check"></i><b>13.1</b> Shiny Events</a></li>
<li class="chapter" data-level="13.2" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-table-btn"><i class="fa fa-check"></i><b>13.2</b> Table Buttons</a></li>
<li class="chapter" data-level="13.3" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-jQuery"><i class="fa fa-check"></i><b>13.3</b> jQuery</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="shiny-output.html"><a href="shiny-output.html"><i class="fa fa-check"></i><b>14</b> Custom Outputs</a><ul>
<li class="chapter" data-level="14.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inner-workings"><i class="fa fa-check"></i><b>14.1</b> Inner-workings</a></li>
<li class="chapter" data-level="14.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-setup"><i class="fa fa-check"></i><b>14.2</b> Setup</a></li>
<li class="chapter" data-level="14.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-r-fun"><i class="fa fa-check"></i><b>14.3</b> Output R Function</a></li>
<li class="chapter" data-level="14.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-html"><i class="fa fa-check"></i><b>14.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="14.5" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-renderer"><i class="fa fa-check"></i><b>14.5</b> Output Renderer</a></li>
<li class="chapter" data-level="14.6" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-binding"><i class="fa fa-check"></i><b>14.6</b> JavaScript Output Binding</a><ul>
<li class="chapter" data-level="14.6.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-title"><i class="fa fa-check"></i><b>14.6.1</b> Boxxy Title</a></li>
<li class="chapter" data-level="14.6.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-value"><i class="fa fa-check"></i><b>14.6.2</b> Boxxy Value</a></li>
<li class="chapter" data-level="14.6.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-bg-color"><i class="fa fa-check"></i><b>14.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="14.6.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-register"><i class="fa fa-check"></i><b>14.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="14.7" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-usage"><i class="fa fa-check"></i><b>14.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="14.8" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inject"><i class="fa fa-check"></i><b>14.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="14.9" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-preprocess"><i class="fa fa-check"></i><b>14.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="shiny-input.html"><a href="shiny-input.html"><i class="fa fa-check"></i><b>15</b> Custom Inputs</a><ul>
<li class="chapter" data-level="15.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-setup"><i class="fa fa-check"></i><b>15.1</b> Setup</a></li>
<li class="chapter" data-level="15.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-intro"><i class="fa fa-check"></i><b>15.2</b> Switch Input HTML and Style</a></li>
<li class="chapter" data-level="15.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-html"><i class="fa fa-check"></i><b>15.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="15.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-binding"><i class="fa fa-check"></i><b>15.4</b> JavaScript Input Binding</a><ul>
<li class="chapter" data-level="15.4.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-find"><i class="fa fa-check"></i><b>15.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="15.4.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-id"><i class="fa fa-check"></i><b>15.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="15.4.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-value"><i class="fa fa-check"></i><b>15.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="15.4.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-set-value"><i class="fa fa-check"></i><b>15.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="15.4.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-receive-msg"><i class="fa fa-check"></i><b>15.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="15.4.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-sub-unsub"><i class="fa fa-check"></i><b>15.4.6</b> Subscribe and Unsubscribe Inputs</a></li>
<li class="chapter" data-level="15.4.7" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-rate-policy"><i class="fa fa-check"></i><b>15.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="15.4.8" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-register"><i class="fa fa-check"></i><b>15.4.8</b> Registering the Input Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-update"><i class="fa fa-check"></i><b>15.5</b> Update Input</a></li>
<li class="chapter" data-level="15.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-excercise"><i class="fa fa-check"></i><b>15.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="shiny-cookies.html"><a href="shiny-cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a><ul>
<li class="chapter" data-level="16.1" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-discover"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-setup"><i class="fa fa-check"></i><b>16.2</b> Setup Project</a></li>
<li class="chapter" data-level="16.3" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="16.4" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
<li class="chapter" data-level="16.5" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-exercises"><i class="fa fa-check"></i><b>16.5</b> Exercises</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="shiny-widgets.html"><a href="shiny-widgets.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a><ul>
<li class="chapter" data-level="17.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-to-r"><i class="fa fa-check"></i><b>17.1</b> Widgets to R</a></li>
<li class="chapter" data-level="17.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handlers"><i class="fa fa-check"></i><b>17.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="17.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-r-to-widgets"><i class="fa fa-check"></i><b>17.3</b> R to Widgets</a><ul>
<li class="chapter" data-level="17.3.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="17.3.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-retrieve"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-proxy"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-update"><i class="fa fa-check"></i><b>17.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="v8.html"><a href="v8.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a><ul>
<li class="chapter" data-level="18.1" data-path="v8.html"><a href="v8.html#v8-installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="v8.html"><a href="v8.html#v8-basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="v8.html"><a href="v8.html#v8-external"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="v8.html"><a href="v8.html#v8-npm"><i class="fa fa-check"></i><b>18.4</b> NPM Packages</a></li>
<li class="chapter" data-level="18.5" data-path="v8.html"><a href="v8.html#v8-pkg"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="v8-ml.html"><a href="v8-ml.html"><i class="fa fa-check"></i><b>19</b> Machine Learning</a><ul>
<li class="chapter" data-level="19.1" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-dependency"><i class="fa fa-check"></i><b>19.1</b> Dependency</a></li>
<li class="chapter" data-level="19.2" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-regression"><i class="fa fa-check"></i><b>19.2</b> Simple Regression</a></li>
<li class="chapter" data-level="19.3" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-exercises"><i class="fa fa-check"></i><b>19.3</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>V Robust JavaScript</b></span></li>
<li class="chapter" data-level="20" data-path="webpack-intro.html"><a href="webpack-intro.html"><i class="fa fa-check"></i><b>20</b> Managing JavaScript</a><ul>
<li class="chapter" data-level="20.1" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-example"><i class="fa fa-check"></i><b>20.1</b> Example</a></li>
<li class="chapter" data-level="20.2" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-browser"><i class="fa fa-check"></i><b>20.2</b> Transpiling</a></li>
<li class="chapter" data-level="20.3" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-minification"><i class="fa fa-check"></i><b>20.3</b> Minification</a></li>
<li class="chapter" data-level="20.4" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-structure"><i class="fa fa-check"></i><b>20.4</b> Bundling and Modules</a></li>
<li class="chapter" data-level="20.5" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-decouple"><i class="fa fa-check"></i><b>20.5</b> Decoupling</a></li>
<li class="chapter" data-level="20.6" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-npm"><i class="fa fa-check"></i><b>20.6</b> NPM</a></li>
<li class="chapter" data-level="20.7" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-conclude"><i class="fa fa-check"></i><b>20.7</b> With R</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html"><i class="fa fa-check"></i><b>21</b> Discover Webpack and NPM</a><ul>
<li class="chapter" data-level="21.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install"><i class="fa fa-check"></i><b>21.1</b> Installation</a><ul>
<li class="chapter" data-level="21.1.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-mac"><i class="fa fa-check"></i><b>21.1.1</b> Mac OS</a></li>
<li class="chapter" data-level="21.1.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-ubuntu"><i class="fa fa-check"></i><b>21.1.2</b> Ubuntu</a></li>
<li class="chapter" data-level="21.1.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-windows"><i class="fa fa-check"></i><b>21.1.3</b> Windows</a></li>
<li class="chapter" data-level="21.1.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-other"><i class="fa fa-check"></i><b>21.1.4</b> Other</a></li>
</ul></li>
<li class="chapter" data-level="21.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-setup"><i class="fa fa-check"></i><b>21.2</b> Set Up the App</a></li>
<li class="chapter" data-level="21.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-init-npm"><i class="fa fa-check"></i><b>21.3</b> Initialise NPM</a></li>
<li class="chapter" data-level="21.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-pkgs"><i class="fa fa-check"></i><b>21.4</b> Installing NPM Packages</a></li>
<li class="chapter" data-level="21.5" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-entry-points"><i class="fa fa-check"></i><b>21.5</b> Entry Point and Output</a></li>
<li class="chapter" data-level="21.6" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-conf"><i class="fa fa-check"></i><b>21.6</b> Configuration File</a></li>
<li class="chapter" data-level="21.7" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-npm-scripts"><i class="fa fa-check"></i><b>21.7</b> NPM scripts</a></li>
<li class="chapter" data-level="21.8" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-webpack-mode"><i class="fa fa-check"></i><b>21.8</b> Source maps</a></li>
<li class="chapter" data-level="21.9" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-bundle"><i class="fa fa-check"></i><b>21.9</b> Bundle</a></li>
<li class="chapter" data-level="21.10" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-internal-dependencies"><i class="fa fa-check"></i><b>21.10</b> Internal Dependencies</a></li>
<li class="chapter" data-level="21.11" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-external-dependencies"><i class="fa fa-check"></i><b>21.11</b> External Dependencies</a></li>
<li class="chapter" data-level="21.12" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export"><i class="fa fa-check"></i><b>21.12</b> Import and Export</a><ul>
<li class="chapter" data-level="21.12.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-named"><i class="fa fa-check"></i><b>21.12.1</b> Named</a></li>
<li class="chapter" data-level="21.12.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-default"><i class="fa fa-check"></i><b>21.12.2</b> Default</a></li>
<li class="chapter" data-level="21.12.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-wrap-up"><i class="fa fa-check"></i><b>21.12.3</b> Wrap-up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="22" data-path="packer-overview.html"><a href="packer-overview.html"><i class="fa fa-check"></i><b>22</b> Webpack with R</a><ul>
<li class="chapter" data-level="22.1" data-path="packer-overview.html"><a href="packer-overview.html#packer-principles"><i class="fa fa-check"></i><b>22.1</b> Principles of packer</a></li>
<li class="chapter" data-level="22.2" data-path="packer-overview.html"><a href="packer-overview.html#packer-scaffolds"><i class="fa fa-check"></i><b>22.2</b> Scaffolds</a></li>
<li class="chapter" data-level="22.3" data-path="packer-overview.html"><a href="packer-overview.html#packer-inputs"><i class="fa fa-check"></i><b>22.3</b> Inputs</a></li>
<li class="chapter" data-level="22.4" data-path="packer-overview.html"><a href="packer-overview.html#packer-r-file"><i class="fa fa-check"></i><b>22.4</b> R file</a></li>
<li class="chapter" data-level="22.5" data-path="packer-overview.html"><a href="packer-overview.html#packer-js-files"><i class="fa fa-check"></i><b>22.5</b> JavaScript Files</a></li>
<li class="chapter" data-level="22.6" data-path="packer-overview.html"><a href="packer-overview.html#packer-bundle"><i class="fa fa-check"></i><b>22.6</b> Bundle</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="packer-adv.html"><a href="packer-adv.html"><i class="fa fa-check"></i><b>23</b> Webpack Advanced</a><ul>
<li class="chapter" data-level="23.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-widgets"><i class="fa fa-check"></i><b>23.1</b> Widgets</a></li>
<li class="chapter" data-level="23.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue"><i class="fa fa-check"></i><b>23.2</b> Shiny with Vue and Bootstrap 4</a><ul>
<li class="chapter" data-level="23.2.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-setup"><i class="fa fa-check"></i><b>23.2.1</b> Setup</a></li>
<li class="chapter" data-level="23.2.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-bs4"><i class="fa fa-check"></i><b>23.2.2</b> Bootstrap 4 Installation</a></li>
<li class="chapter" data-level="23.2.3" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-code"><i class="fa fa-check"></i><b>23.2.3</b> Vue Code</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a><ul>
<li class="chapter" data-level="24.1" data-path="conclusion.html"><a href="conclusion.html#conclusion-performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#conclusion-trial-and-error"><i class="fa fa-check"></i><b>24.2</b> Trial and Error</a></li>
<li class="chapter" data-level="24.3" data-path="conclusion.html"><a href="conclusion.html#conclusion-ux"><i class="fa fa-check"></i><b>24.3</b> Functionality and UX</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="packer-overview" class="section level1">
<h1><span class="header-section-number">Chapter 22</span> Webpack with R</h1>
<p>In the previous chapter, we put together a simple Shiny application using NPM and webpack. Hopefully, it hinted at some of the powerful things webpack can do but also revealed a downside: the overhead in merely creating the project. Moreover, the configuration will change depending on what the project is (application, package, etc.).</p>
<p>In this chapter, we discover the <a href="https://github.com/JohnCoene/packer">packer</a> <span class="citation">(Coene <a href="#ref-R-packer">2020</a>)</span> R package, which provides many convenience functions to create and manage R projects that make use of webpack and NPM.</p>
<div class="sourceCode" id="cb423"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb423-1" title="1"><span class="kw">install.packages</span>(<span class="st">&quot;packer&quot;</span>)</a></code></pre></div>
<div id="packer-principles" class="section level2">
<h2><span class="header-section-number">22.1</span> Principles of packer</h2>
<p>There are a few principles that the packer package follows strictly.</p>
<ol style="list-style-type: decimal">
<li>It only aspires to become a specialised usethis for working with JavaScript and R. As such, it takes inspiration from other packages such as htmlwidgets and devtools.</li>
<li>It will never become a dependency to what you create. It’s in a sense very much like an NPM “developer” dependency; it’s used to develop the project but does not bring any additional overhead to what you’re building.</li>
<li>It should not interfere with the mission of webpack to build more robust JavaScript code. Therefore, packer only builds on top of already, strict R structures, namely packages (where golem can be used to create Shiny applications).</li>
</ol>
</div>
<div id="packer-scaffolds" class="section level2">
<h2><span class="header-section-number">22.2</span> Scaffolds</h2>
<p>Packer is comprised of surprisingly few functions; the most important ones are in the <code>scaffold</code> family. The term scaffold was borrowed from the htmlwidgets package, which features the function <code>scaffoldWidget</code> (already used in this book). The idea of scaffolds in packer is very similar to the <code>scaffoldWidget</code> function: they set up the basic structure for projects.</p>
<p>Whilst htmlwidgets only allows creating scaffolds for widgets; packer allows creating scaffolds for several things, namely:</p>
<ul>
<li>Widgets with <code>scaffold_widget</code></li>
<li>Shiny inputs with <code>scaffold_input</code></li>
<li>Shiny outputs with <code>scaffold_output</code></li>
<li>Shiny extensions with <code>scaffold_extension</code></li>
<li>Golem applications with <code>scaffold_golem</code></li>
</ul>
<p>This gives a few powerful functions that correctly set up webpack. These will build the necessary file structure and configuration depending on the scaffold and the context (whether it is a basic package, a golem application, a package with an existing scaffold, etc.)</p>
<div class="rmdnote">
<p>
One can use multiple scaffolds in a single package or Shiny application.
</p>
</div>
<p>Packer goes beyond merely setting up webpack and NPM; it will also create the necessary R functions, roxygen documentation, and examples, so every scaffold is fully functional out-of-the-box.</p>
<p>With some variations that will be explored in the coming sections, packer’s <code>scaffold</code> functions generally do the following:</p>
<ul>
<li>Initialise npm with <code>npm init</code> and prefills the <code>package.json</code> file</li>
<li>Install webpack and its CLI with <code>npm install webpack webpack-cli --save-dev</code></li>
<li>Creates three webpack configuration files: <code>webpack.common.js</code>, <code>webpack.prod.js</code>, and <code>webpack.dev.js</code></li>
<li>Creates the <code>srcjs</code> directory for the JavaScript source code</li>
<li>Creates raw JavaScript files within the <code>srcjs</code> directory, e.g.: <code>index.js</code></li>
<li>Creates the R functions (if necessary)</li>
<li>Adds the necessary NPM scripts to <code>package.json</code></li>
<li>Adds all relevant files to the <code>.Rbuildignore</code> and <code>.gitignore</code> files</li>
<li>Adds relevant dependencies to the <code>DESCRIPTION</code>, e.g.: <code>shiny</code> when scaffolding an input</li>
<li>Finally, it (optionally) opens interesting files to develop the project in the IDE</li>
</ul>
<p>In the following sections, we unpack some of this as we explore a specific scaffold.</p>
</div>
<div id="packer-inputs" class="section level2">
<h2><span class="header-section-number">22.3</span> Inputs</h2>
<p>In a previous chapter, we explored how to build custom Shiny inputs. Here, we’ll use the packer package to produce a Shiny button that increments at every click; hence we create a package called “increment.”</p>
<div class="sourceCode" id="cb424"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb424-1" title="1">usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;increment&quot;</span>)</a></code></pre></div>
<p>From the root of the package, we scaffold a custom input. Notably, this takes a <code>name</code> argument, which is used as names for the various files, functions, and modules it creates so choose it with care. The function prints some information about the operations it executes.</p>
<p>When run from an interactive session, packer also opens the most pertinent files in the default editor or IDE.</p>
<div class="sourceCode" id="cb425"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb425-1" title="1">packer<span class="op">::</span><span class="kw">scaffold_input</span>(<span class="st">&quot;increment&quot;</span>)</a></code></pre></div>
<div class="sourceCode" id="cb426"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb426-1" title="1">── <span class="ex">Scaffolding</span> shiny input ──────────────────────────────────────── increment ── </a>
<a class="sourceLine" id="cb426-2" title="2">✔ <span class="ex">Initialiased</span> npm</a>
<a class="sourceLine" id="cb426-3" title="3">✔ <span class="ex">Created</span> srcjs/inputs directory</a>
<a class="sourceLine" id="cb426-4" title="4">✔ <span class="ex">Created</span> inst/packer directory</a>
<a class="sourceLine" id="cb426-5" title="5">✔ <span class="ex">webpack</span>, webpack-cli, webpack-merge installed with scope dev</a>
<a class="sourceLine" id="cb426-6" title="6">✔ <span class="ex">Created</span> srcjs/config directory</a>
<a class="sourceLine" id="cb426-7" title="7">✔ <span class="ex">Created</span> webpack config files</a>
<a class="sourceLine" id="cb426-8" title="8">✔ <span class="ex">Created</span> <span class="st">&#39;input&#39;</span> module</a>
<a class="sourceLine" id="cb426-9" title="9">✔ <span class="ex">Created</span> srcjs/index.js</a>
<a class="sourceLine" id="cb426-10" title="10">✔ <span class="ex">Created</span> R file and function</a>
<a class="sourceLine" id="cb426-11" title="11">✔ <span class="ex">Added</span> npm scripts</a>
<a class="sourceLine" id="cb426-12" title="12"></a>
<a class="sourceLine" id="cb426-13" title="13">── <span class="ex">Adding</span> files to <span class="st">&#39;.gitignore&#39;</span> and <span class="st">&#39;.Rbuildignore&#39;</span> ──</a>
<a class="sourceLine" id="cb426-14" title="14"></a>
<a class="sourceLine" id="cb426-15" title="15">✔ <span class="ex">Setting</span> active project to <span class="st">&#39;/javascript-for-r/code/increment&#39;</span></a>
<a class="sourceLine" id="cb426-16" title="16">✔ <span class="ex">Adding</span> <span class="st">&#39;^srcjs$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-17" title="17">✔ <span class="ex">Adding</span> <span class="st">&#39;^node_modules$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-18" title="18">✔ <span class="ex">Adding</span> <span class="st">&#39;^package\\.json$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-19" title="19">✔ <span class="ex">Adding</span> <span class="st">&#39;^package-lock\\.json$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-20" title="20">✔ <span class="ex">Adding</span> <span class="st">&#39;^webpack\\.dev\\.js$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-21" title="21">✔ <span class="ex">Adding</span> <span class="st">&#39;^webpack\\.prod\\.js$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-22" title="22">✔ <span class="ex">Adding</span> <span class="st">&#39;^webpack\\.common\\.js$&#39;</span> to <span class="st">&#39;.Rbuildignore&#39;</span></a>
<a class="sourceLine" id="cb426-23" title="23">✔ <span class="ex">Adding</span> <span class="st">&#39;node_modules&#39;</span> to <span class="st">&#39;.gitignore&#39;</span></a>
<a class="sourceLine" id="cb426-24" title="24"></a>
<a class="sourceLine" id="cb426-25" title="25">── <span class="ex">Adding</span> packages to Imports ──</a>
<a class="sourceLine" id="cb426-26" title="26"></a>
<a class="sourceLine" id="cb426-27" title="27">✔ <span class="ex">Adding</span> <span class="st">&#39;shiny&#39;</span> to Imports field in DESCRIPTION</a>
<a class="sourceLine" id="cb426-28" title="28">● <span class="ex">Refer</span> to functions with <span class="kw">`</span><span class="fu">shiny::fun()</span><span class="kw">`</span></a>
<a class="sourceLine" id="cb426-29" title="29">✔ <span class="ex">Adding</span> <span class="st">&#39;htmltools&#39;</span> to Imports field in DESCRIPTION</a>
<a class="sourceLine" id="cb426-30" title="30">● <span class="ex">Refer</span> to functions with <span class="kw">`</span><span class="fu">htmltools::fun()</span><span class="kw">`</span></a>
<a class="sourceLine" id="cb426-31" title="31"></a>
<a class="sourceLine" id="cb426-32" title="32">── <span class="ex">Scaffold</span> built ──</a>
<a class="sourceLine" id="cb426-33" title="33"></a>
<a class="sourceLine" id="cb426-34" title="34">ℹ <span class="ex">Run</span> <span class="kw">`</span><span class="ex">bundle</span><span class="kw">`</span> to build the JavaScript files</a></code></pre></div>
<p>The scaffold creates the file structure below. Notice that <code>increment</code> was used as the name of some files and that packer creates three webpack configuration files; one for development, another for production, and a third that contains configuration shared across those two modes.</p>
<p>It created one R file, <code>increment.R</code>, which contains the exported input function named <code>incrementInput</code>. It also created the <code>inst/packer</code> directory, which is currently empty but will eventually contain the bundled JavaScript file(s).</p>
<p>The function also initialised NPM, which created the <code>node_modules</code> directory, as well as the <code>package.json</code> and <code>package-lock.json</code>, packer also added the necessary scripts to <code>package.json</code> so one should not need to interact with those files directly.</p>
<p>Finally, it also created the <code>srcjs</code> directory containing core JavaScript files to produce the input binding.</p>
<pre><code>.
├── DESCRIPTION
├── NAMESPACE
├── R
│   ├── increment.R
├── inst
│   └── packer
├── node_modules
│   └── ...
├── package.json
├── srcjs
│   ├── config
│   ├── inputs
│   └── index.js
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js</code></pre>
<p>In the following sections, we break down those files to better understand what packer scaffolded and how to use it.</p>
</div>
<div id="packer-r-file" class="section level2">
<h2><span class="header-section-number">22.4</span> R file</h2>
<p>The R file contains the <code>incrementInput</code> function. Notably, the function contains the necessary dependency, although it currently looks for a file that is yet created (we’ll bundle the JavaScript later). Also, of importance is the class attribute set for the input: <code>incrementBinding</code>. As you might remember, this class will be referenced in the JavaScript binding’s <code>find</code> method.</p>
<div class="sourceCode" id="cb428"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb428-1" title="1">incrementInput &lt;-<span class="st"> </span><span class="cf">function</span>(inputId, <span class="dt">value =</span> <span class="dv">0</span>){</a>
<a class="sourceLine" id="cb428-2" title="2"></a>
<a class="sourceLine" id="cb428-3" title="3">  <span class="kw">stopifnot</span>(<span class="op">!</span><span class="kw">missing</span>(inputId))</a>
<a class="sourceLine" id="cb428-4" title="4">  <span class="kw">stopifnot</span>(<span class="kw">is.numeric</span>(value))</a>
<a class="sourceLine" id="cb428-5" title="5"></a>
<a class="sourceLine" id="cb428-6" title="6">  dep &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</a>
<a class="sourceLine" id="cb428-7" title="7">    <span class="dt">name =</span> <span class="st">&quot;incrementBinding&quot;</span>,</a>
<a class="sourceLine" id="cb428-8" title="8">    <span class="dt">version =</span> <span class="st">&quot;1.0.0&quot;</span>,</a>
<a class="sourceLine" id="cb428-9" title="9">    <span class="dt">src =</span> <span class="kw">c</span>(<span class="dt">file =</span> <span class="kw">system.file</span>(<span class="st">&quot;packer&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;increment&quot;</span>)),</a>
<a class="sourceLine" id="cb428-10" title="10">    <span class="dt">script =</span> <span class="st">&quot;increment.js&quot;</span></a>
<a class="sourceLine" id="cb428-11" title="11">  )</a>
<a class="sourceLine" id="cb428-12" title="12"></a>
<a class="sourceLine" id="cb428-13" title="13">  <span class="kw">tagList</span>(</a>
<a class="sourceLine" id="cb428-14" title="14">    dep,</a>
<a class="sourceLine" id="cb428-15" title="15">    tags<span class="op">$</span><span class="kw">button</span>(</a>
<a class="sourceLine" id="cb428-16" title="16">      <span class="dt">id =</span> inputId,</a>
<a class="sourceLine" id="cb428-17" title="17">      <span class="dt">class =</span> <span class="st">&quot;incrementBinding btn btn-default&quot;</span>,</a>
<a class="sourceLine" id="cb428-18" title="18">      <span class="dt">type =</span> <span class="st">&quot;button&quot;</span>,</a>
<a class="sourceLine" id="cb428-19" title="19">      value</a>
<a class="sourceLine" id="cb428-20" title="20">    )</a>
<a class="sourceLine" id="cb428-21" title="21">  )</a>
<a class="sourceLine" id="cb428-22" title="22">}</a></code></pre></div>
<p>Note that packer does not use the namespace of functions (e.g., <code>shiny::tagList</code>). Instead, it uses the roxygen2 tags to import the necessary functions: <code>@importFrom Shiny tags tagList</code>. Rather nicely, packer also created an example in the roxygen documentation. We’ll run this later after we’ve bundled the JavaScript.</p>
<div class="sourceCode" id="cb429"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb429-1" title="1"><span class="co">#&#39; @examples </span></a>
<a class="sourceLine" id="cb429-2" title="2"><span class="co">#&#39; library(shiny)</span></a>
<a class="sourceLine" id="cb429-3" title="3"><span class="co">#&#39; </span></a>
<a class="sourceLine" id="cb429-4" title="4"><span class="co">#&#39; ui &lt;- fluidPage(</span></a>
<a class="sourceLine" id="cb429-5" title="5"><span class="co">#&#39;  incrementInput(&quot;theId&quot;, 0)</span></a>
<a class="sourceLine" id="cb429-6" title="6"><span class="co">#&#39; )</span></a>
<a class="sourceLine" id="cb429-7" title="7"><span class="co">#&#39; </span></a>
<a class="sourceLine" id="cb429-8" title="8"><span class="co">#&#39; server &lt;- function(input, output){</span></a>
<a class="sourceLine" id="cb429-9" title="9"><span class="co">#&#39; </span></a>
<a class="sourceLine" id="cb429-10" title="10"><span class="co">#&#39;  observeEvent(input$theId, {</span></a>
<a class="sourceLine" id="cb429-11" title="11"><span class="co">#&#39;    print(input$theId)</span></a>
<a class="sourceLine" id="cb429-12" title="12"><span class="co">#&#39;  })</span></a>
<a class="sourceLine" id="cb429-13" title="13"><span class="co">#&#39; </span></a>
<a class="sourceLine" id="cb429-14" title="14"><span class="co">#&#39; }</span></a>
<a class="sourceLine" id="cb429-15" title="15"><span class="co">#&#39; </span></a>
<a class="sourceLine" id="cb429-16" title="16"><span class="co">#&#39; if(interactive())</span></a>
<a class="sourceLine" id="cb429-17" title="17"><span class="co">#&#39;  shinyApp(ui, server)</span></a></code></pre></div>
</div>
<div id="packer-js-files" class="section level2">
<h2><span class="header-section-number">22.5</span> JavaScript Files</h2>
<p>In the <code>srcjs/inputs</code> directory, packer created <code>increment.js</code>. This code contains the JavaScript binding for the increment button. As a reminder, one is not limited to a single scaffold. We could scaffold another input, the JavaScript binding of which would be placed alongside this file, also in <code>srcjs/inputs</code>.</p>
<div class="sourceCode" id="cb430"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb430-1" title="1"><span class="im">import</span> $ <span class="im">from</span> <span class="st">&#39;jquery&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb430-2" title="2"><span class="im">import</span> <span class="st">&#39;shiny&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb430-3" title="3"></a>
<a class="sourceLine" id="cb430-4" title="4"><span class="at">$</span>(document).<span class="at">on</span>(<span class="st">&quot;click&quot;</span><span class="op">,</span> <span class="st">&quot;button.incrementBinding&quot;</span><span class="op">,</span> </a>
<a class="sourceLine" id="cb430-5" title="5">  <span class="kw">function</span>(evt) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-6" title="6">    <span class="co">// evt.target is the button that was clicked</span></a>
<a class="sourceLine" id="cb430-7" title="7">    <span class="kw">var</span> el <span class="op">=</span> <span class="at">$</span>(<span class="va">evt</span>.<span class="at">target</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-8" title="8"></a>
<a class="sourceLine" id="cb430-9" title="9">    <span class="co">// Set the button&#39;s text to its current value plus 1</span></a>
<a class="sourceLine" id="cb430-10" title="10">    <span class="va">el</span>.<span class="at">text</span>(<span class="at">parseInt</span>(<span class="va">el</span>.<span class="at">text</span>()) <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-11" title="11"></a>
<a class="sourceLine" id="cb430-12" title="12">    <span class="co">// Raise an event to signal that the value changed</span></a>
<a class="sourceLine" id="cb430-13" title="13">    <span class="va">el</span>.<span class="at">trigger</span>(<span class="st">&quot;change&quot;</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-14" title="14">  <span class="op">}</span></a>
<a class="sourceLine" id="cb430-15" title="15">)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-16" title="16"></a>
<a class="sourceLine" id="cb430-17" title="17"><span class="kw">var</span> incrementBinding <span class="op">=</span> <span class="kw">new</span> <span class="va">Shiny</span>.<span class="at">InputBinding</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb430-18" title="18"></a>
<a class="sourceLine" id="cb430-19" title="19"><span class="va">$</span>.<span class="at">extend</span>(incrementBinding<span class="op">,</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb430-20" title="20">  <span class="dt">find</span><span class="op">:</span> <span class="kw">function</span>(scope) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-21" title="21">    <span class="cf">return</span> <span class="at">$</span>(scope).<span class="at">find</span>(<span class="st">&quot;.incrementBinding&quot;</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-22" title="22">  <span class="op">},</span></a>
<a class="sourceLine" id="cb430-23" title="23">  <span class="dt">getValue</span><span class="op">:</span> <span class="kw">function</span>(el) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-24" title="24">    <span class="cf">return</span> <span class="at">parseInt</span>(<span class="at">$</span>(el).<span class="at">text</span>())<span class="op">;</span></a>
<a class="sourceLine" id="cb430-25" title="25">  <span class="op">},</span></a>
<a class="sourceLine" id="cb430-26" title="26">  <span class="dt">setValue</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> value) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-27" title="27">    <span class="at">$</span>(el).<span class="at">text</span>(value)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-28" title="28">  <span class="op">},</span></a>
<a class="sourceLine" id="cb430-29" title="29">  <span class="dt">subscribe</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> callback) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-30" title="30">    <span class="at">$</span>(el).<span class="at">on</span>(<span class="st">&quot;change.incrementBinding&quot;</span><span class="op">,</span> <span class="kw">function</span>(e) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-31" title="31">      <span class="at">callback</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb430-32" title="32">    <span class="op">}</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-33" title="33">  <span class="op">},</span></a>
<a class="sourceLine" id="cb430-34" title="34">  <span class="dt">unsubscribe</span><span class="op">:</span> <span class="kw">function</span>(el) <span class="op">{</span></a>
<a class="sourceLine" id="cb430-35" title="35">    <span class="at">$</span>(el).<span class="at">off</span>(<span class="st">&quot;.incrementBinding&quot;</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-36" title="36">  <span class="op">}</span></a>
<a class="sourceLine" id="cb430-37" title="37"><span class="op">}</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb430-38" title="38"></a>
<a class="sourceLine" id="cb430-39" title="39"><span class="va">Shiny</span>.<span class="va">inputBindings</span>.<span class="at">register</span>(</a>
<a class="sourceLine" id="cb430-40" title="40">  incrementBinding<span class="op">,</span> <span class="st">&quot;increment.incrementBinding&quot;</span></a>
<a class="sourceLine" id="cb430-41" title="41">)<span class="op">;</span></a></code></pre></div>
<p>The <code>srcjs/index.js</code> file was also created; it imports the JavaScript binding detailed above with <code>import './inputs/increment.js';</code>. Notably, by default, packer does not bundle all of these files into one; <code>index.js</code> is only populated for convenience in the event one would want to change this behaviour. Instead, packer uses <code>srcjs/inputs/increment.js</code> as an entry point. It will handle multiple entry points, so every input, output, widgets, etc. are bundled separately. This is done so one can import those dynamically.</p>
</div>
<div id="packer-bundle" class="section level2">
<h2><span class="header-section-number">22.6</span> Bundle</h2>
<p>You can then run <code>packer::bundle</code> to bundle the JavaScript. The entry points and output directories will depend on the scaffold, Shiny inputs’ bundles are placed in the <code>inst/packer</code> directory unless this was run from a golem application, in which case the output is automatically changed to golem’s standard.</p>
<div class="sourceCode" id="cb431"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb431-1" title="1">packer<span class="op">::</span><span class="kw">bundle</span>()</a></code></pre></div>
<p>By default packer will bundle the files for production, this can be managed with the functions <code>packer::bundle_dev()</code> and <code>packer::bundle_prod()</code>.</p>
<p>Once the JavaScript is bundled, we can install or load the package with <code>devtools::load_all</code> and use the example that was created for us to test the input.</p>
<div class="sourceCode" id="cb432"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb432-1" title="1"><span class="kw">library</span>(shiny)</a>
<a class="sourceLine" id="cb432-2" title="2"></a>
<a class="sourceLine" id="cb432-3" title="3">ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb432-4" title="4">  <span class="kw">incrementInput</span>(<span class="st">&quot;theId&quot;</span>, <span class="dv">0</span>)</a>
<a class="sourceLine" id="cb432-5" title="5">)</a>
<a class="sourceLine" id="cb432-6" title="6"></a>
<a class="sourceLine" id="cb432-7" title="7">server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</a>
<a class="sourceLine" id="cb432-8" title="8"></a>
<a class="sourceLine" id="cb432-9" title="9">  <span class="kw">observeEvent</span>(input<span class="op">$</span>theId, {</a>
<a class="sourceLine" id="cb432-10" title="10">    <span class="kw">print</span>(input<span class="op">$</span>theId)</a>
<a class="sourceLine" id="cb432-11" title="11">  })</a>
<a class="sourceLine" id="cb432-12" title="12"></a>
<a class="sourceLine" id="cb432-13" title="13">}</a>
<a class="sourceLine" id="cb432-14" title="14"></a>
<a class="sourceLine" id="cb432-15" title="15"><span class="cf">if</span>(<span class="kw">interactive</span>())</a>
<a class="sourceLine" id="cb432-16" title="16">  <span class="kw">shinyApp</span>(ui, server)</a></code></pre></div>
<p>No code was written, yet we have a fully-functional input! We’ll leave ir at this: it’s not only meant to create increment buttons, but this sets up a solid base for the developer to customise the code and conveniently create a different input.</p>
<p>It is worth noting that we built a Shiny input from within a package, this is meant to be exported and used in Shiny applications elsewhere, but were one to run these same steps from a golem application packer would adapt the output path so that the input can be used directly in the application.</p>

</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-packer">
<p>Coene, John. 2020. <em>Packer: An Opinionated Framework for Using ’Javascript’</em>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="webpack-intro-discover.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="packer-adv.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/clipboard.min.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/7-03-webpack-packer.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
